<template>
  <el-dialog v-model="visible" :title="'工单详情：' + (ticket?.title || '')" width="800px" @close="$emit('close')">
    <div v-if="ticket">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="工单号">{{ ticket.id }}</el-descriptions-item>
        <el-descriptions-item label="客户">{{ ticket.customer }}</el-descriptions-item>
        <el-descriptions-item label="优先级">{{ priorityLabel(ticket.priority) }}</el-descriptions-item>
        <el-descriptions-item label="状态">{{ statusLabel(ticket.status) }}</el-descriptions-item>
        <el-descriptions-item label="分配客服">{{ ticket.assignee }}</el-descriptions-item>
        <el-descriptions-item label="创建时间">{{ ticket.createdAt }}</el-descriptions-item>
        <el-descriptions-item label="标签">{{ ticket.tags?.join(', ') }}</el-descriptions-item>
      </el-descriptions>
      <el-divider>协同处理人</el-divider>
      <div class="co-staff-bar">
        <el-select
          v-model="coStaffToAdd"
          placeholder="添加协同客服"
          filterable
          clearable
          style="width:120px;margin-right:8px;"
          :disabled="isReadOnly"
        >
          <el-option
            v-for="a in allAssignees"
            :key="a.id"
            :label="a.label"
            :value="a.id"
            :disabled="ticket.coAssignees && ticket.coAssignees.some(staff => staff.id === a.id)"
          >
            <el-avatar :src="a.avatar" :size="20" style="margin-right:4px;" />{{ a.label }}
          </el-option>
        </el-select>
        <el-button
          size="small"
          type="primary"
          @click="onConfirmAddCoStaff"
          :disabled="!coStaffToAdd || isReadOnly"
          style="margin-right:12px;"
        >确定</el-button>
        <div class="co-staff-list">
          <el-tag
            v-for="(staff, idx) in ticket.coAssignees"
            :key="staff.id"
            closable
            :disable-transitions="true"
            @close="removeCoStaff(idx)"
            class="co-staff-tag"
          >
            <el-avatar :src="staff.avatar" :size="20" style="margin-right:4px;" />
            {{ staff.name }}
          </el-tag>
        </div>
      </div>
      <el-divider>工单描述</el-divider>
      <div style="margin-bottom: 16px;">{{ ticket.description }}</div>
      <el-tabs v-model="mainTab" class="mb-2">
        <el-tab-pane label="评论区" name="comment">
          <div v-if="ticket.comments && ticket.comments.length">
            <el-timeline>
              <el-timeline-item v-for="c in ticket.comments" :key="c.id" :timestamp="c.time">
                <b>{{ c.author }}</b>：{{ c.content }}
                <div v-if="c.attachments && c.attachments.length" class="comment-attachments">
                  <el-link v-for="a in c.attachments" :key="a.url" :href="a.url" target="_blank" type="primary" style="margin-right:8px;">
                    <el-icon v-if="a.type==='image'" style="vertical-align:middle;"><Picture /></el-icon>
                    <el-icon v-else style="vertical-align:middle;"><Document /></el-icon>
                    <span style="margin-left:4px;">{{ a.name }}</span>
                  </el-link>
                </div>
              </el-timeline-item>
            </el-timeline>
          </div>
          <div v-else style="color:#aaa;">暂无评论</div>
        </el-tab-pane>
        <el-tab-pane label="操作日志/流转记录" name="timeline">
          <div v-if="ticket.timeline && ticket.timeline.length">
            <el-timeline>
              <el-timeline-item v-for="(item, idx) in ticket.timeline" :key="idx" :timestamp="item.time">
                <b>{{ item.action }}</b>
                <span v-if="item.operator">（操作人：{{ item.operator }}）</span>
                <span v-if="item.remark"> - {{ item.remark }}</span>
              </el-timeline-item>
            </el-timeline>
          </div>
          <div v-else style="color:#aaa;">暂无流转记录</div>
        </el-tab-pane>
      </el-tabs>
      <el-divider>快捷回复 / 知识库</el-divider>
      <el-tabs v-model="replyTab">
        <el-tab-pane label="快捷回复" name="quick">
          <el-tag v-for="qr in quickReplies" :key="qr.content" class="mr-2" @click="onQuickReply(qr)">{{ qr.content }}</el-tag>
        </el-tab-pane>
        <el-tab-pane label="知识库" name="knowledge">
          <el-select v-model="knowledgeCategory" placeholder="全部分类" clearable class="mb-2" style="width:100%">
            <el-option v-for="cat in categories as Array<{id:number;name:string;parentId:null}>" :key="cat.id" :label="cat.name" :value="cat.id" />
          </el-select>
          <el-input v-model="knowledgeSearch" placeholder="搜索知识库..." class="mb-2" />
          <el-collapse>
            <el-collapse-item v-for="kb in filteredKnowledge" :key="kb.id" :title="kb.title" @click="onKnowledgeClick(kb)">
              <div>{{ kb.content }}</div>
            </el-collapse-item>
          </el-collapse>
        </el-tab-pane>
      </el-tabs>
      <el-divider>添加评论</el-divider>
      <el-form @submit.prevent class="flex items-end gap-2">
        <el-input
          v-model="replyContent"
          placeholder="请输入评论内容，可点击上方快捷回复/知识库快速填充"
          type="textarea"
          :rows="2"
          style="flex:1"
          :disabled="isReadOnly"
          @keyup.enter.exact.prevent="onSendReply"
          ref="replyInputRef"
        />
        <el-popover
          placement="top"
          width="220"
          trigger="click"
          v-model:visible="emojiVisible"
        >
          <div class="emoji-list">
            <span v-for="emoji in emojiList" :key="emoji" class="emoji-item" @click="onEmojiSelect(emoji)">{{ emoji }}</span>
          </div>
          <template #reference>
            <el-button size="small" :disabled="isReadOnly">😀</el-button>
          </template>
        </el-popover>
        <el-upload
          class="upload-demo"
          :auto-upload="false"
          :show-file-list="true"
          :file-list="replyAttachments"
          :disabled="isReadOnly"
          :on-change="onAttachmentChange"
          :on-remove="onAttachmentRemove"
          :limit="5"
          style="margin-left:8px;"
        >
          <el-button size="small" :disabled="isReadOnly">上传附件</el-button>
        </el-upload>
        <el-button type="primary" @click="onSendReply" :disabled="isReadOnly">发送</el-button>
      </el-form>
      <div v-if="isReadOnly" style="color:#f56c6c;margin-top:8px;">已完成/已关闭工单不可再回复</div>
      <div v-if="canMarkResolved || canMarkClosed" style="margin-top:16px;display:flex;gap:12px;">
        <el-button v-if="canMarkResolved" type="success" @click="onMarkResolved">标记为已完成</el-button>
        <el-button v-if="canMarkClosed" type="info" @click="onMarkClosed">标记为已关闭</el-button>
      </div>
    </div>
    <template #footer>
      <el-button @click="$emit('close')">关闭</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessageBox, ElMessage } from 'element-plus'
import { Picture, Document } from '@element-plus/icons-vue'
import { assignees as allAssigneesMock } from '@/mock/mock-tickets'
import type { Ref } from 'vue'
const props = defineProps({
  ticket: { type: Object, required: true },
  quickReplies: { type: Array, required: true },
  knowledgeBase: { type: Array, required: true },
  categories: { type: Array, required: true }
})
const emit = defineEmits(['close'])
const visible = ref(true)
const mainTab = ref('comment')
const replyTab = ref('quick')
const knowledgeSearch = ref('')
const replyContent = ref('')
const replyAttachments = ref<any[]>([])
const isReadOnly = computed(() => props.ticket.status === 'resolved' || props.ticket.status === 'closed')
const canMarkResolved = computed(() => props.ticket.status === 'open' || props.ticket.status === 'processing')
const canMarkClosed = computed(() => props.ticket.status === 'open' || props.ticket.status === 'processing')
const knowledgeCategory = ref('')
const filteredKnowledge = computed(() => {
  let list = props.knowledgeBase as Array<{ id: number; title: string; categoryId: number; content: string; tags: string[]; keywords: string[]; status: string; weight: number; views: number; helpful: number; created: string; updated: string }>
  if (knowledgeCategory.value) {
    list = list.filter((kb) => String(kb.categoryId) === String(knowledgeCategory.value))
  }
  if (knowledgeSearch.value) {
    list = list.filter((kb) => kb.title.includes(knowledgeSearch.value) || kb.content.includes(knowledgeSearch.value))
  }
  return list
})
const coStaffToAdd = ref('')
const allAssignees = allAssigneesMock
const replyInputRef = ref()
const emojiVisible = ref(false)
const emojiList = ['😀','😁','😂','🤣','😃','😄','😅','😆','😉','😊','😍','😘','😜','🤔','😭','😡','👍','👏','🙏','🎉','💪','❤️','🔥','🌹','😎','🤗','😏','😱','😴','😇','😋','😢','😤','��','😳']
function onConfirmAddCoStaff() {
  if (!coStaffToAdd.value || !props.ticket.coAssignees) return
  const found = allAssignees.find(a => a.id === coStaffToAdd.value)
  if (found && !props.ticket.coAssignees.some(staff => staff.id === found.id)) {
    props.ticket.coAssignees.push({ id: found.id, name: found.label, avatar: found.avatar })
  }
  coStaffToAdd.value = ''
}
function removeCoStaff(idx: number) {
  if (!props.ticket.coAssignees) return
  props.ticket.coAssignees.splice(idx, 1)
}
function onQuickReply(qr: { content: string }) {
  if (isReadOnly.value) return
  replyContent.value = qr.content
}
function onKnowledgeClick(kb: { id: number; title: string; categoryId: number; content: string; tags: string[]; keywords: string[]; status: string; weight: number; views: number; helpful: number; created: string; updated: string }) {
  if (isReadOnly.value) return
  replyContent.value = kb.content
}
function onAttachmentChange(file: any, fileList: any[]) {
  replyAttachments.value = fileList.map((f: any) => ({
    name: f.name,
    url: f.url || URL.createObjectURL(f.raw),
    type: f.raw && f.raw.type.startsWith('image') ? 'image' : 'file'
  }))
}
function onAttachmentRemove(file: any, fileList: any[]) {
  replyAttachments.value = fileList.map((f: any) => ({
    name: f.name,
    url: f.url || (f.raw && URL.createObjectURL(f.raw)),
    type: f.raw && f.raw.type.startsWith('image') ? 'image' : 'file'
  }))
}
function onSendReply() {
  if (isReadOnly.value) return
  const content = replyContent.value.trim()
  if (!content && !replyAttachments.value.length) return
  const newComment = {
    id: Date.now(),
    author: '当前客服',
    content,
    time: new Date().toLocaleString(),
    type: 'public',
    attachments: replyAttachments.value.map(a => ({ ...a }))
  }
  if (!props.ticket.comments) props.ticket.comments = []
  props.ticket.comments.push(newComment)
  replyContent.value = ''
  replyAttachments.value = []
}
function onEmojiSelect(emoji: string) {
  // 插入到光标处
  nextTick(() => {
    const textarea = replyInputRef.value?.textarea
    if (textarea) {
      const start = textarea.selectionStart
      const end = textarea.selectionEnd
      replyContent.value = replyContent.value.slice(0, start) + emoji + replyContent.value.slice(end)
      nextTick(() => {
        textarea.focus()
        textarea.selectionStart = textarea.selectionEnd = start + emoji.length
      })
    } else {
      replyContent.value += emoji
    }
  })
  emojiVisible.value = false
}
function onMarkResolved() {
  ElMessageBox.confirm('确定要将该工单标记为已完成吗？', '操作确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'success',
  }).then(() => {
    props.ticket.status = 'resolved'
    ElMessage.success('工单已标记为已完成')
  })
}
function onMarkClosed() {
  ElMessageBox.confirm('确定要将该工单标记为已关闭吗？', '操作确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'info',
  }).then(() => {
    props.ticket.status = 'closed'
    ElMessage.success('工单已标记为已关闭')
  })
}
watch(() => props.ticket, () => {
  visible.value = true
  replyContent.value = ''
  replyAttachments.value = []
  mainTab.value = 'comment'
})
function priorityLabel(val: string) {
  switch (val) {
    case 'urgent': return '紧急'
    case 'high': return '高'
    case 'medium': return '中'
    case 'low': return '低'
    default: return val
  }
}
function statusLabel(val: string) {
  switch (val) {
    case 'open': return '待处理'
    case 'processing': return '处理中'
    case 'waiting': return '等待回复'
    case 'resolved': return '已完成'
    case 'closed': return '已关闭'
    default: return val
  }
}
</script>

<style scoped>
.mr-2 { margin-right: 8px; }
.mb-2 { margin-bottom: 12px; }
.flex { display: flex; }
.items-end { align-items: flex-end; }
.gap-2 { gap: 8px; }
.comment-attachments { margin-top: 4px; }
.co-staff-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.co-staff-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.co-staff-tag {
  display: flex;
  align-items: center;
}
.emoji-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  max-width: 200px;
}
.emoji-item {
  font-size: 22px;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 4px;
  transition: background 0.2s;
}
.emoji-item:hover {
  background: #f5f5f5;
}
</style> 